package com.duqc.freemarker;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.*;

import static java.sql.DriverManager.getConnection;

/**
 * @ClassName TableInfoGenerator
 * @Description TableInfoGenerator
 * @Author duqc
 * @Date 2022/10/12
 **/
@Slf4j
public class TableInfoGenerator {

    /**
     * 代码根路径
     */
    private static final String PATH = System.getProperty("user.dir");

    private static final String[] TABLE_NAME_LIST = new String[]{
            "ability_evaluation",
            "audit_configure",
            "audit_instance",
            "audit_task",
            "common_online_dblink",
            "credit_info",
            "credit_list",
            "credit_punishment",
            "custom_column",
            "custom_datasource",
            "custom_datasource_relation",
            "custom_datasource_table",
            "custom_form",
            "custom_form_datasource",
            "custom_page",
            "custom_page_datasource",
            "custom_table",
            "employee_base",
            "enterprise_tag",
            "evaluation_template",
            "evaluation_template_cardinality",
            "evaluation_template_comment",
            "evaluation_template_index",
            "group_project",
            "innovate_index_base",
            "innovate_index_list",
            "innovate_index_source",
            "project_accept",
            "project_accept_apply_record",
            "project_base",
            "project_cert_book_record",
            "project_cert_template",
            "project_config_template_page",
            "project_custom_page_template",
            "project_execution",
            "project_execution_record",
            "project_handle_list",
            "project_important_list",
            "project_index",
            "project_initiation",
            "project_item_template",
            "project_merits_rate",
            "project_merits_rate_list",
            "project_mid_rate",
            "project_mid_rate_record",
            "project_mid_rate_review_info",
            "project_mid_rate_template",
            "project_modify_list",
            "project_money_list",
            "project_plan_dept",
            "project_review_group",
            "project_task_book",
            "project_task_book_record",
            "project_task_book_template",
            "project_template",
            "recommended_to_unit",
            "review_expert_list",
            "review_score_info",
            "tag_category",
            "tag_info",
            "tag_metadata",
            "unit_base_list",
            "unit_business_list",
            "unit_high_tech_extend_list",
            "unit_intellectual_property_list",
            "unit_iur_list",
            "unit_personnel_list",
            "unit_platform_list",
            "unit_product_list",
            "unit_project_list",
            "unit_shareholder_list",
            "unit_whitelist",
            "zdy_project_01_01",
            "zdy_project_acceptance_apply_base",
            "zdy_project_attachment",
            "zdy_project_base",
            "zdy_project_execute_base",
            "zdy_project_fiscal_filings",
            "zdy_project_important_base",
            "zdy_project_important_book_base",
            "zdy_project_important_introduce",
            "zdy_project_intro",
            "zdy_project_mid_rate_apply_base",
            "zdy_project_msp_basic_info",
            "zdy_project_network",
            "zdy_task_book_accept_apply",
            "zdy_task_book_base",
            "zdy_task_book_jxzpb",
            "zdy_test_flow_contract",
            "zdy_test_flow_contract_detail",
            "zdy_test_flow_delivery_detail",
            "zdy_test_flow_leave",
            "zdy_test_table_one"
    };

    /**
     * 生成word文件
     *
     * @param dataMap      word中需要展示的动态数据，用map集合来保存
     * @param templateName word模板名称，例如：test.ftl
     * @param filePath     文件生成的目标路径，例如：D:/wordFile/
     * @param fileName     生成的文件名称，例如：test.doc
     */
    @SneakyThrows
    public static void createWord(Map dataMap, String templateName, String filePath, String fileName) {
        try {
            //创建配置实例
            Configuration configuration = new Configuration(Configuration.getVersion());
            //设置编码
            configuration.setDefaultEncoding("UTF-8");
            //ftl模板文件
            configuration.setDirectoryForTemplateLoading(new File(String.format("%s\\src\\main\\resources\\module", PATH)));
            configuration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
            //获取模板
            Template template = configuration.getTemplate(templateName);
            //输出文件
            File outFile = new File(filePath + File.separator + fileName);
            //如果输出目标文件夹不存在，则创建
            if (!outFile.getParentFile().exists()) {
                outFile.getParentFile().mkdirs();
            }
            //将模板和数据模型合并生成文件
            Writer out = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(outFile.toPath()), StandardCharsets.UTF_8));
            //生成文件
            template.process(dataMap, out);
            //关闭流
            out.flush();
            out.close();
        } catch (Exception e) {
            log.info(e.getMessage(), e);
        }
    }

    private void generator() {
        String url = "jdbc:mysql://192.168.6.244:11123/tech-proj-plan?useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&rewriteBatchedStatements=true&allowMultiQueries=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai";
        String username = "root";
        String password = "poEV56Gjhqq4";
        List<TableNames> data = new ArrayList<>();
        Properties props = new Properties();
        props.setProperty("remarks", "true");
        props.setProperty("user", username);
        props.setProperty("password", password);
        props.setProperty("useInformationSchema", "true");
        try (Connection connection = getConnection(url, props)) {
            DatabaseMetaData metaData = connection.getMetaData();
            for (int i = 0; i < TABLE_NAME_LIST.length; i++) {
                ResultSet resultSet = metaData.getColumns(connection.getCatalog(), "service_matters_sys", TABLE_NAME_LIST[i], "%");
                List<TableInfo> list = new ArrayList<>();
                int id = 1;
                while (resultSet.next()) {
                    //Mysql字段类型
                    String typeName = resultSet.getString("TYPE_NAME");
                    //字段名称
                    String columnName = resultSet.getString("COLUMN_NAME");
                    //字段注释
                    String remarks = resultSet.getString("REMARKS");
                    //字段注释
                    String size = resultSet.getString("COLUMN_SIZE");
                    TableInfo tableInfo = new TableInfo();
                    tableInfo.setId(String.valueOf(id++));
                    tableInfo.setName(columnName);
                    tableInfo.setType(typeName);
                    tableInfo.setLength(size);
                    tableInfo.setComment(remarks);
                    list.add(tableInfo);
                }
                TableNames tableNames = new TableNames();
                tableNames.setTableInfo(list);
                tableNames.setTableName(TABLE_NAME_LIST[i]);
                data.add(tableNames);
            }
            Map<String, Object> listInfo = new HashMap<>(16);
            listInfo.put("listInfo", data);
            List<TableInfo> tableInfos = new ArrayList<>();
            for (int i = 0; i < TABLE_NAME_LIST.length; i++) {
                ResultSet tables = metaData.getTables(connection.getCatalog(), null, TABLE_NAME_LIST[i], null);
                String remarks = "";
                while (tables.next()) {
                    remarks = tables.getString("REMARKS");
                }

                TableInfo tableInfo = new TableInfo();
                tableInfo.setId(String.valueOf(i + 1));
                tableInfo.setName(TABLE_NAME_LIST[i]);
                tableInfo.setComment(remarks);
                tableInfos.add(tableInfo);
            }
            listInfo.put("tables", tableInfos);
            String filePath = "D:\\";
            String fileOnlyName = "table.doc";
            TableInfoGenerator.createWord(listInfo, "table2.ftl", filePath, fileOnlyName);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    public static void main(String[] args) {
        new TableInfoGenerator().generator();
    }

}
